﻿using System;
using System.Collections.Generic;
using NHibernate;
using br.com.portocs.unidaacademico.dominio;
using br.com.portocs.unidaacademico.repositorio.config;

namespace br.com.portocs.unidaacademico.repositorio
{
    [Serializable]
    public class RepositorioBase<TEntidade>
        where TEntidade : IEntidadeBase
    {
        
        #region Membros

        protected ISession Session { get; set; }

        #endregion

        #region Construtor

        /// <summary>
        /// Construtor que receve um objeto de
        /// sessão
        /// </summary>        
        public RepositorioBase()
        {
            Session = Autoconfiguracao.Sessao;
        }

        public RepositorioBase(ISession sessao)
        {
            Session = sessao;
        }

        #endregion

        #region Métodos

        /// <summary>
        /// Responsável por salvar uma entidade
        /// no banco de dados
        /// </summary>
        /// <param name="entidade"></param>
        public virtual TEntidade SalvarOuAtualizar(TEntidade entidade)
        {
            TEntidade T;
            using (var trans = Session.BeginTransaction())
            {
                T = (TEntidade)Session.SaveOrUpdateCopy(entidade);
                trans.Commit();                
            }
            return T;
        }

        /// <summary>
        /// Responsável por salvar uma entidade
        /// no banco de dados
        /// </summary>
        /// <param name="entidade"></param>
        public virtual long Salvar(TEntidade entidade)
        {            
            using (var trans = Session.BeginTransaction())
            {
                entidade.Id = (long)Session.Save(entidade);
                trans.Commit();
            }
            return entidade.Id;
        }


        /// <summary>
        /// Responsável por salvar uma entidade
        /// no banco de dados
        /// </summary>
        /// <param name="entidade"></param>
        public virtual void Atualizar(TEntidade entidade)
        {
            using (var trans = Session.BeginTransaction())
            {
                Session.Update(entidade);
                trans.Commit();
            }
        }

        /// <summary>
        /// Responsável por excluir um objeto
        /// do banco de dados
        /// </summary>
        /// <param name="id">Id da entidade</param>
        public virtual void Excluir(long id)
        {
            var entidade = RecuperarPorId(id);
            if (entidade == null)
                return;
            Excluir(entidade);
        }


        /// <summary>
        /// Responsável por excluir um objeto
        /// do banco de dados
        /// </summary>
        /// <param name="entidade">Instância da ntidade</param>
        public virtual void Excluir(TEntidade entidade)
        {
            using (var trans = Session.BeginTransaction())
            {
                Session.Delete(entidade);
                trans.Commit();
            }
        }

        /// <summary>
        /// Responsável por recuperar um registro 
        /// por seu Id
        /// </summary>
        /// <param name="id">Id da entidade</param>
        /// <returns></returns>
        public virtual TEntidade RecuperarPorId(long id)
        {
            Session.Clear();

            var entidade = Session.Get<TEntidade>(id);
            return entidade;
        }

        /// <summary>
        /// Responsável por recuperar todos os registros
        /// em uma lista      
        /// </summary>
        /// <returns></returns>
        public virtual IList<TEntidade> RecuperaTodos()
        {
            Session.Clear();
            
            var entidades = Session
                .CreateCriteria(typeof(TEntidade))                
                .List<TEntidade>();
            return entidades;
        }

        #endregion

    }
}